首页 > 试题广场 >

识别有效的IP地址和掩码并进行分类统计

[编程题]识别有效的IP地址和掩码并进行分类统计
  • 热度指数:376503 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}在本题中,我们需要处理地址信息,其由 IP 地址和子网掩码组成,这两者均形如 \texttt{,由四段数字组成(每一个 \texttt{`*'} 表示一个数字),每一段的数字均为 0255 之间的一个整数,每段数字之间以点分隔。

\hspace{15pt}我们定义五类 IP 地址:
\hspace{23pt}\bullet\,A 类:\texttt{
\hspace{23pt}\bullet\,B 类:\texttt{
\hspace{23pt}\bullet\,C 类:\texttt{
\hspace{23pt}\bullet\,D 类:\texttt{
\hspace{23pt}\bullet\,E 类:\texttt{
\hspace{15pt}我们定义私有 IP 地址:
\hspace{23pt}\bullet\,\texttt{
\hspace{23pt}\bullet\,\texttt{
\hspace{23pt}\bullet\,\texttt{

\hspace{15pt}我们定义合法的子网掩码为:将掩码的每一段数字依次转换为八位长度的二进制字符串并进行拼接,这个字符串必须由若干个连续的 1 后跟若干个连续的 0 组成,才视为子网掩码合法。例如,掩码 \texttt{ 转换拼接得到字符串 \texttt{11111111 11111110 11111111 00000000},显然不合法;掩码 \texttt{ 转换拼接得到字符串 \texttt{11111111 11111111 11111111 11111000},合法。注意,全为 1 或全为 0 的掩码也视为非法。
\hspace{15pt}我们定义错误的 IP 地址和错误的子网掩码为不符合上述定义的 IP 地址和子网掩码。例如,格式错误、数字超出范围等等。

\hspace{15pt}现在,你需要分类统计 A、B、C、D、E 类地址的数量、错误 IP 或错误子网掩码的数量、私有 IP 的数量。

\hspace{15pt}特别地:
\hspace{23pt}\bullet\,类似 \texttt{\texttt{ 的 IP 地址不计入任何类别,也不计入非法统计,直接跳过;
\hspace{23pt}\bullet\,一个 IP 既可计入私有 IP,也可计入五类地址之一,二者分别累计。

输入描述:
\hspace{15pt}本题将会给出 1 \leqq T \leqq 1000 条地址信息,确切数字未知,您需要一直读取至文件结尾;您也可以参考 牛客网在线判题系统使用帮助 获得更多的使用帮助。每条地址信息描述如下:
\hspace{15pt}每行输入一个 \texttt{ 形式的 IP 地址和一个 \texttt{ 形式的子网掩码,中间用波浪线(\sim)分隔。保证 \texttt{`*'} 要么为空,要么是一个 0255 间的整数。


输出描述:
\hspace{15pt}在一行上输出七个整数,分别代表 A 类地址数、B 类地址数、C 类地址数、D 类地址数、E 类地址数、错误 IP 或错误子网掩码数、私有 IP 数。
示例1

输入

10.70.44.68~1.1.1.5
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0

输出

1 0 1 0 0 2 1

说明

\hspace{15pt}在这个样例中: 
\hspace{23pt}\bullet\,第一条地址信息:掩码非法;
\hspace{23pt}\bullet\,第二条地址信息:IP 格式和掩码均合法,属于 A 类;
\hspace{23pt}\bullet\,第三条地址信息:IP 格式和掩码均合法,属于 C 类私有地址;
\hspace{23pt}\bullet\,第四条地址信息:IP 格式非法。
\hspace{15pt}统计得到 1 个 A 类,0 个 B 类,1 个 C 类,0 个 D 类,0 个 E 类,2 个错误条目,1 个私有地址。
示例2

输入

0.201.56.50~255.255.255.0
127.201.56.50~255.255.111.255

输出

0 0 0 0 0 0 0

说明

\hspace{15pt}在这个样例中,两条地址信息均属于上方提示中提到的特殊 IP 地址,不需要处理,直接跳过。特别需要注意地,第二条地址的子网掩码是非法的。但是因为该条为特殊 IP 地址,此优先级更高,所以不进入统计。

备注:
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-05-30 更新题面。
2. 2024-12-16 更新题面。
题目里写1.1.1.5转换成二进制是1.1.1.101,然后我怎么做怎么不对,万万没想到转换成二进制要补零
发表于 2025-03-06 01:27:55 回复(0)
不想改了,直接说重点吧:
1.最优先的是特殊ip,只要是特殊ip,跳过就好;
2.再来判断子网掩码是否符合规范,由于我是自己写了一个转二进制的函数,所以有一个错误一直没找到,这个也是最重要的,这个ip是8位二进制,也就是说,前面需要补0!!!比如255.255.255.32,二进制是10000,但是前面的0要补充完整,也就是00010000,这样255转换成二进制后,1的后面还是有0,所以不符合规范。
3.最后先判断是否私有ip,如果是则判断是否是ABC(因为私有ip肯定是ABC的一种),否则直接判断是否是ABCDE。
import sys
# 五类IP
def judge_1(x):
    type_ip = None
    data = []
    for num in x:
        if num == '':
            type_ip = False
            return type_ip
        else:
            num = int(num)
            data.append(num)
    if 1 <= data[0] <= 126 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255:
        type_ip = 'A'
    elif 128 <= data[0] <= 191 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255:
        type_ip = 'B'
    elif 192 <= data[0] <= 223 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255:
        type_ip = 'C'
    elif 224 <= data[0] <= 239 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255:
        type_ip = 'D'
    elif 240 <= data[0] <= 255 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255:
        type_ip = 'E'
    return type_ip


# 私有IP
def judge_2(x):
    data = []
    type_ip = None
    for num in x:
        if num == '':
            type_ip = False
            return type_ip
        else:
            num = int(num)
            data.append(num)
    if data[0] == 10 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255:
        type_ip = True
    elif data[0] == 172 and 16 <= data[1] <= 31 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255:
        type_ip = True
    elif data[0] == 192 and data[1] == 168 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255:
        type_ip = True
    return type_ip


# 二进制转换
def bin_convert(data):
    bin_num = []
    if data == 0:
        bin_num.append('0')
    else:
        while True:
            if data // 2 > 0:
                if data % 2 > 0:
                    bin_num.append('1')
                    data //= 2
                elif data % 2 == 0:
                    bin_num.append('0')
                    data //= 2
            elif data // 2 == 0:
                bin_num.append('1')
                break
    # 要补0,如果位数小于8的话
    # 补零的个数:
    n = 8 - len(bin_num)
    # 这里转换是列表,如果不转换为字符串,后面会和子码里面转换为字符串冲突
    bin_num = ''.join(bin_num)
    bin_num = bin_num + n * '0'
    bin_num = bin_num[::-1]
    return bin_num

# 子网掩码判定
def judge_mask(x):
    data = []
    result = None
    for num in x:
        if num == '':
            result = False
            break
        else:
            num = int(num)
            data.append(num)
    mask = []
    # 全为0或者1的都是非法的
    i = 0
    while i <= 3:
        mask.append(bin_convert(data[i]))
        i += 1
    mask = "".join(mask)
     # 转换为字符串后,可以以0来分割
    mask = mask.split('0')
    if len(mask) == 1:
        result = False
        return result
    conunt = 0
    for element in mask:
        if element != '':
            conunt += 1
    # 如果分割后的非空元素个数大于1个,说明后面还有1
    if conunt > 1:
        result = False
    # 如果非空元素等于0,说明全是1
    elif conunt == 0:
        result = False
    else:
        result = True
    return result
# 特殊IP判定
def judge_specialip(x):
    type_ip = None
    data = []
    for num in x:
        if num == '':
            type_ip = False
            return type_ip
        else:
            num = int(num)
            data.append(num)
    data[0] = int(data[0])
    if data[0] == 0&nbs***bsp;data[0] == 127:
        type_ip = True
    return type_ip


type_A = 0
type_B = 0
type_C = 0
type_D = 0
type_E = 0
type_error = 0
type_private = 0
ip_info = []
for line in sys.stdin:
    p = line.split()
    ip_ipmask = p[0].split('~')
    ip = ip_ipmask[0].split('.')
    ipmask = ip_ipmask[1].split('.')
    if len(ip) != 4&nbs***bsp;len(ipmask) != 4:
        continue
    # 特殊ip优先级最高,先判定
    else:
        if judge_specialip(ip):
            pass
        else:
            if judge_mask(ipmask):
                if judge_2(ip):
                    type_private += 1
                    if judge_1(ip) == 'A':
                        type_A += 1
                    elif judge_1(ip) == 'B':
                        type_B += 1
                    elif judge_1(ip) == 'C':
                        type_C += 1
                elif judge_1(ip) == 'A':
                    type_A += 1
                elif judge_1(ip) == 'B':
                    type_B += 1
                elif judge_1(ip) == 'C':
                    type_C += 1
                elif judge_1(ip) == 'D':
                    type_D += 1
                elif judge_1(ip) == 'E':
                    type_E += 1
            else:
                type_error += 1
print(f"{type_A} {type_B} {type_C} {type_D} {type_E} {type_error} {type_private}")


发表于 2025-03-03 11:20:50 回复(0)
a = 0
b = 0
c = 0
d = 0
e = 0

wrong_ip = 0
private_ip = 0

def ip_to_int(ip):
    """将IP地址转换为整数"""
    a, b, c, d = map(int, ip.split("."))
    return (a << 24) + (b << 16) + (c << 8) + d  # 左移运算实现权重计算

def judge_mask(mask):
    a, b, c, d = map(int, mask.split("."))
    binary_mask = str(bin(a))[2:].zfill(8)+str(bin(b))[2:].zfill(8)+str(bin(c))[2:].zfill(8)+str(bin(d))[2:].zfill(8)
    if "01" in binary_mask or set(binary_mask) in [{"0"}, {"1"}]:  # 如果出现 "01",说明 `1` 和 `0` 不是连续的

        return False

ip_a = ["1.0.0.0","126.255.255.255"]
ip_b = ["128.0.0.0","191.255.255.255"]
ip_c = ["192.0.0.0","223.255.255.255"]
ip_d = ["224.0.0.0","239.255.255.255"]
ip_e = ["240.0.0.0","255.255.255.255"]

private_a = ["10.0.0.0","10.255.255.255"]
private_b = ["172.16.0.0","172.31.255.255"]
private_c = ["192.168.0.0","192.168.255.255"]

ip_a_area = [ip_to_int(ip_a[0]),ip_to_int(ip_a[1])]
ip_b_area = [ip_to_int(ip_b[0]),ip_to_int(ip_b[1])]
ip_c_area = [ip_to_int(ip_c[0]),ip_to_int(ip_c[1])]
ip_d_area = [ip_to_int(ip_d[0]),ip_to_int(ip_d[1])]
ip_e_area = [ip_to_int(ip_e[0]),ip_to_int(ip_e[1])]

private_a_area = [ip_to_int(private_a[0]),ip_to_int(private_a[1])]
private_b_area = [ip_to_int(private_b[0]),ip_to_int(private_b[1])]
private_c_area = [ip_to_int(private_c[0]),ip_to_int(private_c[1])]

import sys

# 读取所有输入行
lines = sys.stdin.readlines()
for line in lines:
    ip, mask = line.split("~")

    if ip.split('.')[0] in ['0','127']:
        pass
    else:
        if judge_mask(mask) is False:
            wrong_ip += 1
        else:
            if private_a_area[0]<=ip_to_int(ip)<=private_a_area[1] or private_b_area[0]<=ip_to_int(ip)<=private_b_area[1] or private_c_area[0]<=ip_to_int(ip)<=private_c_area[1]:
                private_ip += 1
            if ip_a_area[0]<=ip_to_int(ip)<=ip_a_area[1]:
                # print(ip, mask,type(mask))
                a+=1
            elif ip_b_area[0]<=ip_to_int(ip)<=ip_b_area[1]:
                b+=1
            elif ip_c_area[0]<=ip_to_int(ip)<=ip_c_area[1]:
                c += 1
            elif ip_d_area[0]<=ip_to_int(ip)<=ip_d_area[1]:
                d += 1
            elif ip_e_area[0]<=ip_to_int(ip)<=ip_e_area[1]:
                e += 1

print(a, b, c, d, e, wrong_ip, private_ip)
发表于 2025-03-02 16:10:25 回复(0)
127.201.56.50~255.255.111.255 这个IP+掩码不需要统计掩码的错误吗?
发表于 2025-02-28 17:48:16 回复(0)
我们定义合法的子网掩码:
将 IP 地址转换为二进制后,必须由若干个连续的 1 后跟若干个连续的 0 组成;
为什么题目不说明白?一定要把子网掩码ip转换为32位的二进制数字,为什么不说??
我把31.255.255.0转换为:
1111111111111111111110
不说明白就是合法的了
还有这个错误,一个题出两个错你们好意思?
气死我了,浪费我两个小时


发表于 2025-01-16 06:35:16 回复(0)
求助各位大佬们:
这14个是不是都非法啊,我的代码判断出来这14个均非法,我自己也感觉他们子网掩码都非法,但是为啥答案是13个非法啊

225.240.129.203~255.110.255.255
153.63.21.56~255.255.58.255
73.245.52.119~255.255.154.0
139.124.188.91~255.255.255.100
127.201.56.50~255.255.111.255
253.237.54.56~255.86.0.0
64.189.222.111~255.255.255.139
24.22.21.206~255.255.90.255
110.156.20.173~255.153.0.0
73.81.221.180~255.255.255.255
73.198.13.199~255.0.15.0
244.248.31.171~255.255.255.255
121.124.37.157~255.0.0.226
125.88.217.249~255.255.74.255
发表于 2025-01-14 20:11:48 回复(0)
题出错了吧! 两个例子自相矛盾! 第一个例子因为127而忽略了错误计数, 所以总错误是2
10.70.44.68~255.254.255.0的子网掩码非法,19..0.~255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
1.0.0.1~255.0.0.0是无误的A类地址;
192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
127.69.131.137~255.70.255.255 计数忽略
所以最终的结果为1 0 1 0 0 2 1 
第二个例子却没有因为 0 或 127 忽略错误计数, 如按例子1的做法, 这里应该为0, 但是答案却为2, 所以对了题1就没法对题2, 对了题2就没法对题1啊!
输入:
0.201.56.50~255.255.111.255
127.201.56.50~255.255.111.255
输出:
0 0 0 0 0 2 0
说明:
类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略

发表于 2024-11-05 19:55:10 回复(0)
ip_lst = []
mask_lst = []
res = [0]*7
def is_valid(addr, mask=False):
    if mask and (addr == '255.255.255.255'&nbs***bsp;addr == '0.0.0.0'):
        return False
    bin_addr = ''
    segs = addr.split('.')
    for i in range(len(segs)):
        if not segs[i]:
            return False
        segs[i] = int(segs[i])
        if segs[i] < 0&nbs***bsp;segs[i] > 255:
            return False
        if mask:
            bin_addr += '{:0>8}'.format(bin(segs[i])[2:])
    if bin_addr:
        inx_0 = bin_addr.find('0')
        inx_1 = bin_addr.rfind('1')
        if inx_0 - inx_1 == 1:
            return True
        else:
            return False
    return True

while True:
    try:
        ip, mask = input().split('~')
        segs = list(map(int, ip.split('.')))
        # 跳过0.*.*.*和127.*.*.*类地址
        if segs[0] == 0&nbs***bsp;segs[0] == 127:
            continue
        if not is_valid(ip)&nbs***bsp;not is_valid(mask, True):
            res[-2] += 1
        else:
            # 判断A类地址和私网1
            if 1 <= segs[0] <= 126:
                if segs[0] == 10:
                    res[-1] += 1
                res[0] += 1
            # 判断B类地址和私网2
            elif 128 <= segs[0] <= 191:
                if segs[0] == 172 and (16 <= segs[1] <= 31):
                    res[-1] += 1
                res[1] += 1
            # 判断C类地址和私网3
            elif 192 <= segs[0] <= 223:
                if segs[0] == 192 and segs[1] == 168:
                    res[-1] += 1
                res[2] += 1
            # 判断D类地址
            elif 224 <= segs[0] <= 239:
                res[3] += 1
            # 判断E类地址
            elif 240 <= segs[0] <= 255:
                res[4] += 1
    except:
        break
print(' '.join(map(str, res)))

""" 注意
0.*.*.*和127.*.*.*类地址不参与分类判断,要最先排除,否则可能影响子网掩码不合法数量异常

"""

发表于 2024-08-11 18:48:13 回复(0)
发表于 2024-06-21 21:53:05 回复(0)
from re import T
import sys

def check_private(ip_list):
    check_head = ip_list[0]
    check_tail = ip_list[1]
    if check_head == 10:
        return True
    elif check_head == 172 and 16 <= check_tail <= 31:
        return True
    elif check_head == 192 and check_tail == 168:
        return True
    else:
        return False

ip_type = {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "ERROR": 0, "PRIVATE": 0}
for line in sys.stdin:
    ip, saveip = map(str, line.split("~"))
    saveip = saveip.replace("\n","")
    # print(ip, saveip)
    ip_valid_list = [int(ip_valid) for ip_valid in ip.split(".") if ip_valid.isdigit()]
    save_ip_valid_list = [int(ip_valid) for ip_valid in saveip.split(".") if ip_valid.isdigit()]
    # print(ip_valid_list)
    if len(ip_valid_list) < 4 or len(save_ip_valid_list) < 4:
        ip_type["ERROR"] += 1
        continue
    else:
        if ip_valid_list[0] == 0 or ip_valid_list[0] == 127:
            continue
            # ip_type["ERROR"] += 1
        else:
            ip_head = int(ip_valid_list[0])
           
            ip_bool_list = []
            for x in ip_bool_list:
                if x == 255 or x == 0:
                    ip_bool_list.append(True)
                else:
                    ip_bool_list.append(False)
            ip_bool = all(x==True for x in ip_bool_list)
           
            save_ip_bool_list = []
            for x in save_ip_valid_list:
                if x == 255 or x == 0:
                    save_ip_bool_list.append(True)
                else:
                    save_ip_bool_list.append(False)
            save_ip_bool = all(x==True for x in save_ip_bool_list)
            if all( x==0 for x in save_ip_valid_list) or all( x==255 for x in save_ip_valid_list):
                save_ip_bool = False

            if ip_bool and save_ip_bool and 1 <= ip_head <= 126:
                ip_type["A"] += 1
            elif ip_bool and save_ip_bool and 128 <= ip_head <= 191:
                ip_type["B"] += 1
            elif ip_bool and save_ip_bool and 192 <= ip_head <= 223:
                ip_type["C"] += 1
            elif ip_bool and save_ip_bool and 224 <= ip_head <= 239:
                ip_type["D"] += 1
            elif ip_bool and save_ip_bool and 240 <= ip_head <= 255:
                ip_type["E"] += 1
            else:
                ip_type["ERROR"] += 1
                continue
            private_ip_bool = check_private(ip_valid_list)
            if private_ip_bool:
                ip_type["PRIVATE"] += 1
           
for k, v in ip_type.items():
    print(v,end=" ")

发表于 2024-05-17 15:44:02 回复(0)
纯粹的业务题,要看清题目的要求,我卡了老半天
编辑于 2024-04-01 17:40:31 回复(0)
做了一晚上,我真废材啊
import sys

A, B, C, D, E, X, Y = 0, 0, 0, 0, 0, 0, 0

# 判断是否是数字字符串的序列
def not_all_int(string_list):
    for s in string_list:
        try:
            int(s)  # 尝试将字符串转换为整数
        except:
            return True  # 如果转换失败,则返回true并跳出函数
    return False  # 如果所有字符串都能成功转换为整数,则返回false

# 字符串的序列转化为int的序列
def list_str_to_int(string_list):  # 字符串转化成int
    int_list = list(map(int, string_list))
    return int_list

# 把整数序列转化为大长的二进制数表示,注意到前面多了个0b1 但是空位是全的。
def list_int_to_big_bin(int_list):
    int_numb = (
        int_list[0] * (2 ** 24)
        + int_list[1] * (2 ** 16)
        + int_list[2] * (2 ** 8)
        + int_list[3]
        + 2 ** 32
    )
    bin_numb = bin(int_numb)
    return bin_numb

# 判断子网掩码是否错误,错误则返回True
def sub_mask_false(bin_numb):
    str_numb = str(bin_numb)

    if str_numb == "0b1" + "0000" * 8 or str_numb == "0b1" + "1111" * 8:
        return True
    else:
        for i in range(len(str_numb) - 1):
            if str_numb[i] == "0" and str_numb[i + 1] == "1":
                return True
        return False

# 判断是否是私网,如果是,返回True
def private_net_ip(string_list):
    int_list = list_str_to_int(string_list)
    if int_list[0] == 10:
        return True
    elif int_list[0] == 172 and int_list[1] >= 16 and int_list[1] <= 31:
        return True
    elif int_list[0] == 192 and int_list[1] == 168:
        return True
    else:
        return False

# 判断ip地址是否在正确区间
# 如果第一个1或者127说明不合法,返回True,合法则返回False
def ip_address_false(string_list):
    ip_int_list = list_str_to_int(string_list)
    if ip_int_list[0] == 0 or ip_int_list[0] == 127:
        return True
    else:
        return False

# 正文
for line in sys.stdin:
    # 切割开~,分成两半
    str_0 = line.split("~")
    # 如果不足2个,就直接跳出去
    if len(str_0) < 2:
        break
    # 分别拿出来,切去换行符\n
    str_IP_Address_0 = str_0[0]
    str_subnet_mask_0 = str_0[1].replace("\n", "")
    # 切割开. 形成字符串的序列,这样的['10','20','15','40']
    str_IP_Address = str_IP_Address_0.split(".")
    str_subnet_mask = str_subnet_mask_0.split(".")

    # 判断是不是数字组成的字符串
    if not_all_int(str_IP_Address) or not_all_int(str_subnet_mask):
        X += 1
        continue

    # 判断IP地址是不是0或者127开头,如果是,直接舍去,不计数
    if ip_address_false(str_IP_Address):
        continue

    # 把子网掩码字符串变成整数,再拼成长的二进制数
    bin_numb = list_int_to_big_bin(list_str_to_int(str_subnet_mask))
    # 判断这个子网掩码是否合法
    if sub_mask_false(bin_numb):
        X += 1
        continue

    # 判断一个合法的ip地址,属于ABCDE
    int_list = list_str_to_int(str_IP_Address)
    if int_list[0] >= 1 and int_list[0] <= 126:
        A += 1  # A
    elif int_list[0] >= 128 and int_list[0] <= 191:
        B += 1  # B
    elif int_list[0] >= 192 and int_list[0] <= 223:
        C += 1  # C
    elif int_list[0] >= 224 and int_list[0] <= 239:
        D += 1  # D
    elif int_list[0] >= 240 and int_list[0] <= 255:
        E += 1  # E

    # 判断是否是私网
    if private_net_ip(str_IP_Address):
        Y += 1

print(A, B, C, D, E, X, Y)


发表于 2024-03-30 01:36:41 回复(0)
import sys
address = []
mask = []
A = 0
B = 0
C = 0
D = 0
E = 0
error = 0
private = 0
for line in sys.stdin:
    a = line.split("~")
    address.append(a[0])
    mask.append(a[1][:-1])

# 判断掩码是否合法
def is_valid_mask(m):
    x = ["255","254","252","248","240","224","192", "128","0"]

    m1 = m.split(".")
    n = 0
    sum1 = 0 # 四个码的和
    for code in m1:
        sum1 += int(code)
        if n == 1 and code != "0":
            return False 
        if code != "255":
            if code in x:
                n = 1
            else:
                return False
    if sum1 == 0&nbs***bsp;sum1 == 255 * 4:
        return False
    return True

# 判断IP地址是否合法
def is_valid_address(a):
    try:
        result = False
        for i in a.split("."):
            if int(i)>=0 and int(i)<=255:
                result = True
        return result
    except:
        return False

# 判断IP地址是否为私有IP
def is_private_IP(ip):
    a = ip.split(".")
    if a[0] == "10":
        return True
    if a[0] == "172":
        if int(a[1]) >= 16 and int(a[1]) <= 31:
            return True
    if a[0] == "192":
        if int(a[1]) == 168:
            return True
    return False


for i in range(len(address)):
    a = address[i].split(".")
    if a[0] == "0"&nbs***bsp;a[0] == "127":
        continue
    if is_valid_address(address[i]):        
        
        if is_valid_mask(mask[i]):
            # a = address[i].split(".")
            if int(a[0]) >= 1 and int(a[0]) <= 126:
                A += 1
            if int(a[0]) >= 128 and int(a[0]) <= 191:
                B += 1
            if int(a[0]) >= 192 and int(a[0]) <= 223:
                C += 1
            if int(a[0]) >= 224 and int(a[0]) <= 239:
                D += 1
            if int(a[0]) >= 240 and int(a[0]) <= 255:
                E += 1
            if is_private_IP(address[i]):
                private += 1 
        else:
            error += 1
            
    else:
        error += 1
    
print(A,B,C,D,E,error,private)

发表于 2024-02-28 02:44:02 回复(0)
第6组测试用例,子网掩码数据:
预期不应该是14组错误吗?官方预期是13组

提取出的错误掩码如下:
['255', '110', '255', '255']
1111111111011101111111111111111
['255', '255', '58', '255']
111111111111111111101011111111
['255', '255', '154', '0']
1111111111111111100110100
['255', '255', '255', '100']
1111111111111111111111111100100
['255', '255', '111', '255']
1111111111111111110111111111111
['255', '86', '0', '0']
11111111101011000
['255', '255', '255', '139']
11111111111111111111111110001011
['255', '255', '90', '255']
1111111111111111101101011111111
['255', '153', '0', '0']
111111111001100100
['255', '255', '255', '255']
11111111111111111111111111111111
['255', '0', '15', '0']
11111111011110
['255', '255   ', '255', '255']
11111111111111111111111111111111
['255', '0', '0', '226']
111111110011100010
['255', '255', '74', '255']
1111111111111111100101011111111

测试用例原数据如下:
25.240.129.203~255.110.255.255
183.181.49.4~255.0.0.0
172.177.113.45~255.0.0.0
176.134.46.246~255.0.0.0
153.63.21.56~255.255.58.255
23.135.167.228~255.0.0.0
204.58.47.149~255.0.0.0
113.33.181.46~255.255.255.0
73.245.52.119~255.255.154.0
23.214.47.71~255.0.0.0
139.124.188.91~255.255.255.100
142.94.192.197~255.0.0.0
53.173.252.202~255.0.0.0
127.201.56.50~255.255.111.255
118.251.84.111~255.0.0.0
130.27.73.170~255.0.0.0
253.237.54.56~255.86.0.0
64.189.222.111~255.255.255.139
148.77.44.147~255.0.0.0
59.213.5.253~255.255.0.0
3.52.119.131~255.255.0.0
213.208.164.145~255.255.0.0
24.22.21.206~255.255.90.255
89.43.34.31~255.0.0.0
9.64.214.75~255.0.0.0
110.156.20.173~255.153.0.0
71.183.242.53~255.255.0.0
119.152.129.100~255.0.0.0
38.187.119.201~255.0.0.0
73.81.221.180~255.255.255.255
73.198.13.199~255.0.15.0
99.42.142.145~255.255.255.0
196.121.115.160~255.0.0.0
226.30.29.206~255.0.0.0
244.248.31.171~255.255.255.255
59.116.159.246~255.0.0.0
121.124.37.157~255.0.0.226
103.42.94.71~255.255.0.0
125.88.217.249~255.255.74.255
73.44.250.101~255.255.255.0
发表于 2023-09-08 21:30:00 回复(0)
import sys

count = [0]*7
n = sys.stdin.readlines()

def IPclassify(IP_class, count, mask_correct):
    while mask_correct == 1:
        if IP_class[0] !='127' and IP_class[0] !='0':
            if IP_class[0] =='' or IP_class[1] =='' or IP_class[2] =='' or IP_class[3] =='':
                count[5] += 1
            elif (int(IP_class[0]) in range(1,127)) and (int(IP_class[1]) in range(0,256))\
            and (int(IP_class[2]) in range(0,256)) and (int(IP_class[3]) in range(0,256)):
                if int(IP_class[0]) == 10:
                    count[6] += 1
                count[0] += 1
            elif  (int(IP_class[0]) in range(128,192)) and (int(IP_class[1]) in range(0,256))\
            and (int(IP_class[2]) in range(0,256)) and (int(IP_class[3]) in range(0,256)):
                if (int(IP_class[0]) == 172) and (int(IP_class[1]) in range(16,32)):
                    count[6] += 1
                count[1] += 1
            elif  (int(IP_class[0]) in range(192,224)) and (int(IP_class[1]) in range(0,256))\
            and (int(IP_class[2]) in range(0,256)) and (int(IP_class[3]) in range(0,256)):
                if (int(IP_class[0]) == 192) and (int(IP_class[1]) == 168):
                    count[6] += 1
                count[2] += 1
            elif  (int(IP_class[0]) in range(224,240)) and (int(IP_class[1]) in range(0,256))\
            and (int(IP_class[2]) in range(0,256)) and (int(IP_class[3]) in range(0,256)):  
                count[3] += 1
            elif  (int(IP_class[0]) in range(240,256)) and (int(IP_class[1]) in range(0,256))\
            and (int(IP_class[2]) in range(0,256)) and (int(IP_class[3]) in range(0,256)):  
                count[4] += 1
        else:
            pass
        break
    return count

def maskclassify(IP_class,tolbase_str,count,mask_correct):
    if IP_class[0] !='127' and IP_class[0] !='0':
        if ('01' in tolbase_str) or ('1' not in tolbase_str) or ('0' not in tolbase_str):
            count[5] += 1
            mask_correct = 0
            return mask_correct,count
        else:
            mask_correct = 1
            return mask_correct,count
    else:
        mask_correct = 1
        return mask_correct,count

 
def baseconvert(mask_class):
    tolbase = []
    for i in range(len(mask_class)):
        twobase = []
        num = int(mask_class[i])
        if num == 0:
            tolbase.append('00000000')
        else :
            while num > 0:
                twobase.append(str(num%2))
                num = num // 2
            twobase_rev = ''.join(twobase[::-1])
            if len(twobase_rev) < 8:
                twobase_rev = twobase_rev.zfill(8)
            tolbase.append(twobase_rev)
    tolbase_str = ''.join(tolbase)
    return tolbase_str

for i in range(len(n)):
   
    IP = n[i].strip().split('~')[0]
    mask = n[i].strip().split('~')[1]
    IP_class = IP.split('.')
    mask_class = mask.split('.')
    tolbase_str = baseconvert(mask_class)
    #print(tolbase_str)
    mask_correct, count = maskclassify(IP_class, tolbase_str, count, mask_correct=1)
    #print(mask_correct)
    count = IPclassify(IP_class, count, mask_correct)

[print(item, end=' ') for item in count]



   
发表于 2023-09-05 18:01:54 回复(0)
import sys


def judge_ip(ip_list:list[str])->bool:
    flag = False
    if len(ip_list) == 4:
        if ip_list[0] in [str(i) for i in range(1,256)] and ip_list[0] != "127":
            for i in range(1,4):
                if ip_list[i] in [str(i) for i in range(256)]:
                    flag = True
    return flag


def get_ip_class(ip_list:list[str])->str:
    type = ""
    if ip_list[0] in [str(i) for i in range(1,127)]:
        type = "A"
    if ip_list[0] in [str(i) for i in range(128,192)]:
        type = "B"
    if ip_list[0] in [str(i) for i in range(192,224)]:
        type = "C"
    if ip_list[0] in [str(i) for i in range(224,240)]:
        type = "D"
    if ip_list[0] in [str(i) for i in range(240,256)]:
        type = "E"
    return type


def judge_personal_ip(ip_list:list[str])->bool:
    flag = False
    if ip_list[0] == "10":
        flag = True
    elif ip_list[0] == "172" and ip_list[1] in [str(i) for i in range(16,32)]:
        flag = True
    elif ip_list[0] == "192" and ip_list[1] == "168":
        flag = True
    return flag


def judge_mask(mask_list:list[str])->bool:
    flag = False
    sum_temp = 0
    legal_num = []
    for i in range(7,-1,-1):
        sum_temp += pow(2,i)
        legal_num.append(str(sum_temp))

    if len(mask_list) == 4:
        if mask_list[0] in legal_num and mask_list[1]=="0" and mask_list[2]=="0" and mask_list[3]=="0":
            flag = True
        if mask_list[0]=="255" and mask_list[1] in legal_num and mask_list[2]=="0" and mask_list[3]=="0":
            flag = True
        if mask_list[0]=="255" and mask_list[1]=="255" and mask_list[2] in legal_num and mask_list[3]=="0":
            flag = True
        if mask_list[0]=="255" and mask_list[1]=="255" and mask_list[2]=="255" and mask_list[3] in legal_num:
            flag = True
        
        if mask_list[0]=="255" and mask_list[1]=="255" and mask_list[2]=="255" and mask_list[3]=="255":
            flag = False
        if mask_list[0]=="0" and mask_list[1]=="0" and mask_list[2]=="0" and mask_list[3]=="0":
            flag = False
    
    return flag


A,B,C,D,E,wrong,personal = 0,0,0,0,0,0,0
for line in sys.stdin:
    # print(line)
    line = line.rstrip('\n')
    ip,mask = line.split('~')
    ip_list = [i for i in ip.strip(".").split(".") if i != ""]
    mask_list = [i for i in mask.strip(".").split(".") if i != ""]
    # print(ip_list)
    # print(mask_list)
    if ip_list[0] in ["0", "127"]:
        continue
    else:
        if judge_ip(ip_list) and judge_mask(mask_list):
            if judge_personal_ip(ip_list):
                personal += 1
            class_ = get_ip_class(ip_list)
            if class_ == "A":
                A += 1
            if class_ == "B":
                B += 1
            if class_ == "C":
                C += 1
            if class_ == "D":
                D += 1
            if class_ == "E":
                E += 1
        else:
            wrong += 1
print("{} {} {} {} {} {} {}".format(A,B,C,D,E,wrong,personal))


# 重点1:
# 使用 for line in sys.stdin 读进来的line会包括最后一个回车字符'\n',进行后续计算之前一定要记得先使用rstrip('\n')方法去掉
# 重点2:
# 对于ip = "19..0." 这种特殊字符串,单纯使用ip.split('.')得到的ip_list = ['19', '', '0', ''] 会包含空字符串,
# 如果不想包含空字符串,,需要使用ip_list = [part for part in ip.split('.') if part != ''],结果ip_list = ['19', '0']



发表于 2023-08-04 02:00:06 回复(0)
有无大佬帮我看看哪里错了,有一组用例不知道为什么有两个错误ip算a类和d类里去了
import sys 
a,b,c,d,e,err,pri = 0,0,0,0,0,0,0
ipt = []
for line in sys.stdin:
    temp = line.split()[0]
    ipt.append(temp)

for row in ipt:
    ips = row.split('~')[0].split('.')
    ym = row.split('~')[1].split('.') 
    if ips[0]=='0'&nbs***bsp;ips[0]=='127' : continue
    legal = True
    
    for i in ips:
        if not str(i).isdigit():
            legal = False
            break
        if not 0<=int(i)<=255:
            legal = False
            break
    yms = ''

    for j in ym:
        yms += str(bin(int(j)))
    yms = yms.replace('0b','')

    if ('10' not in yms)&nbs***bsp;('01' in yms):
        legal = False
    
    if not legal:
        err += 1
        continue

    if 1<=int(ips[0])<=127: a += 1
    if 128<=int(ips[0])<=191: b += 1
    if 192<=int(ips[0])<=223: c += 1
    if 224<=int(ips[0])<=239: d += 1
    if 240<=int(ips[0])<=255: e += 1
    if int(ips[0])==10: pri += 1
    if int(ips[0])==172 and 16<=int(ips[1])<=31: pri += 1
    if int(ips[0])==192 and int(ips[1])==168: pri += 1
print(a,b,c,d,e,err,pri)


发表于 2023-07-18 15:10:18 回复(0)
# 当ip为0或127开头,则即使子网掩码是错误的,也忽略不计数
import sys

input1 = [i.strip() for i in sys.stdin]

def isR(item,type):
    tmpData = item.split('.')
    if len(tmpData) != 4:
        return False
    else:
        if type=='ip':
            res = []
            for i in tmpData:
                if i =='':
                    res.append(False)
                elif 0<=int(i)<=255: 
                    res.append(True)
                else:
                    res.append(False)
            res = False if False in res else True
            return res
        elif type=='subCode':
            subCode_bin = get_ip_bin(item)
            if '1' not in subCode_bin:
                return False
            elif '0' not in subCode_bin:
                return False
            else:
                if subCode_bin.count('10')==1:
                    a,b = subCode_bin.split('10')
                    if '0' not in a and '1' not in b:
                        return True
                    else:
                        return False
                else:
                    return False
def get_ip_bin(item):
    res = [bin(int(i))[2:] for i in item.split('.')]
    for i in range(4):
        res[i] = '0'*(8-len(res[i]))+res[i]
    return ''.join(res)
def isIn(ipStart,ipEnd,res_ip):
    if int(get_ip_bin(ipStart)) <= int(res_ip) <= int(get_ip_bin(ipEnd)):
        return True
    else:
        return False
countRes = {'A':0,'B':0,'C':0,'D':0,'E':0,'***t_ip':0,'private':0}
for i in range(len(input1)):
    ip,subCode = input1[i].split('~')
    tmp = ip.split('.')
    if tmp[0]=='0'&nbs***bsp;tmp[0]=='127':
        continue
    if isR(ip,'ip') and isR(subCode,'subCode'):
        ip_bin = get_ip_bin(ip)
        subCode_bin = get_ip_bin(subCode)
        res_ip=''
        for j in range(32):
            if ip_bin[j] == '1' and subCode_bin[j] == '1':
                res_ip+='1'
            else:
                res_ip+='0'
        if isIn('1.0.0.0','126.255.255.255',res_ip):
            countRes['A']+=1
        elif isIn('128.0.0.0','191.255.255.255',res_ip):
            countRes['B']+=1
        elif isIn('192.0.0.0','223.255.255.255',res_ip):
            countRes['C']+=1
        elif isIn('224.0.0.0','239.255.255.255',res_ip):
            countRes['D']+=1    
        elif isIn('240.0.0.0','255.255.255.255',res_ip):
            countRes['E']+=1
        if isIn('10.0.0.0','10.255.255.255',res_ip)&nbs***bsp;isIn('172.16.0.0','172.31.255.255',res_ip)&nbs***bsp;isIn('192.168.0.0','192.168.255.255',res_ip):
            countRes['private']+=1
    else:
        countRes['***t_ip']+=1
print(*countRes.values(),sep=' ')

发表于 2023-07-06 15:09:06 回复(0)